package server

import (
	"chitchat_http/model"
	"chitchat_http/util"
	"errors"
	"fmt"
	"github.com/doujunyu/gogo/gogo_log"
	"github.com/doujunyu/gogo/sql_aid"
	"time"
)

// ChatByApplyFriend 申请好友
func ChatByApplyFriend(userId int64, byUserId int64, content string) error {
	t := time.Now().Format(time.RFC3339)
	//判断是否已经是好友
	chatFriendSql, args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?", userId).Where("friend_id = ?", byUserId).ToSql()
	chatFriendData, err := sql_aid.DataToMap(model.PgSql.Query(chatFriendSql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "用户查询失败", err.Error())
		return errors.New("内部错误")
	}
	if len(chatFriendData) != 0 {
		return errors.New("该用户已经和您是好友关系，无需申请")
	}
	//判断是否已经申请
	applySql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("status = ?", model.ChatApplyFriendGroupByStatusWaiting).Where("type_id = ?", model.ChatApplyFriendGroupByTypeIdFriend).Where("user_id = ?", userId).Where("by_user_id = ?", byUserId).ToSql()
	applyData, err := sql_aid.DataToMap(model.PgSql.Query(applySql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "申请查询失败", err.Error())
		return errors.New("内部错误")
	}
	if len(applyData) != 0 {
		return errors.New("请勿重复提交")
	}
	//添加消息和加入队列
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	var applyId int64
	insertData := make(map[string]interface{})
	insertData["user_id"] = userId
	insertData["type_id"] = model.ChatApplyFriendGroupByTypeIdFriend
	insertData["by_user_id"] = byUserId
	insertData["content"] = content
	insertData["status"] = model.ChatApplyFriendGroupByStatusWaiting
	insertData["refused_message"] = ""
	insertData["time_c"] = t
	insertData["time_u"] = t
	insertData["merge_user_ids"] = model.ChatApplyFriendGroupByMergeUserIdsToJson(userId,byUserId)
	applySql, args = sql_aid.PgTable(model.TableByChatApplyFriendGroup).InsertByMap(insertData)
	err = tx.QueryRow(applySql+" RETURNING id", args...).Scan(&applyId)
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "添加申请消息错误", err.Error())
		return errors.New("内部错误")
	}
	//推送申请好友消息
	userSlq, args := sql_aid.PgTable(model.TableByUser).Field("id", "nick", "avatar", "motto").Where("id = ?", userId).ToSql()
	userData, err := sql_aid.DataToMap(model.PgSql.Query(userSlq, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyFriend", "查询用户错误", err.Error())
		return errors.New("内部错误")
	}
	if len(userData) == 0 {
		return errors.New("用户不存在")
	}
	//消息推送
	pushMessage := MessageByStructMain{
		CmdMessage: MessageByApplyFriend,
		ReceiveUserIds: []interface{}{byUserId,userId},
		SendUserID:     userId,
		SendUser:       userData[0],
		Content: map[string]interface{}{
			MessageContentByContent:content,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatByApplyGroup 申请进群组
func ChatByApplyGroup(userId int64, groupId int64, content string)error{
	t := time.Now().Format(time.RFC3339)
	//判断群是否存在
	groupSql,args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?",groupId).ToSql()
	groupData,err := sql_aid.DataToMap(model.PgSql.Query(groupSql,args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询组失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupData) == 0 {
		return errors.New("群组不存在")
	}
	//判断是否存在群组内
	groupFriendSql,args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?",userId).Where("group_id = ?",groupId).ToSql()
	groupFriendSqlData,err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql,args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupFriendSqlData) != 0 {
		return errors.New("您已经存在与群组，无需申请")
	}
	//判断是否有未审核的
	applyGroupSql,args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("type_id = ?",model.ChatApplyFriendGroupByTypeIdGroup).Where("user_id = ?",userId).Where("group_id = ?",groupId).Where("status = ?",model.ChatApplyFriendGroupByStatusWaiting).ToSql()
	applyGroupData,err := sql_aid.DataToMap(model.PgSql.Query(applyGroupSql,args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询申请sql失败", err.Error())
		return errors.New("内部错误")
	}
	if len(applyGroupData) != 0 {
		return errors.New("您已经申请过，无需重复申请")
	}
	//查找组内可审核的成员
	masterUserId := model.ChatGroupFriendByUserCheck(groupId)
	masterUserId = append(masterUserId,userId)
	//发送进组消息
	insertData := make(map[string]interface{})
	insertData["user_id"] = userId
	insertData["type_id"] = model.ChatApplyFriendGroupByTypeIdGroup
	insertData["by_user_id"] = 0
	insertData["group_id"] = groupId
	insertData["content"] = content
	insertData["status"] = model.ChatApplyFriendGroupByStatusWaiting
	insertData["refused_message"] = ""
	insertData["time_c"] = t
	insertData["time_u"] = t
	insertData["merge_user_ids"] = model.ChatApplyFriendGroupByMergeUserIdsToJson(masterUserId...)
	insertSql,args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).InsertByMap(insertData)
	_,err = model.PgSql.Exec(insertSql,args...)
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "申请消息失败", err.Error())
		return errors.New("操作失败")
	}

	groupFriendSql,args = sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?",groupId).WhereIn("identity_id",model.ChatGroupFriendByIdentityIdManager,model.ChatGroupFriendByIdentityIdAdministrator).ToSql()
	groupFriendSqlData,err = sql_aid.DataToMap(model.PgSql.Query(groupFriendSql,args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	//消息推送
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	masterGroup := util.ArrayField(&groupFriendSqlData,"user_id")
	pushMessage := MessageByStructMain{
		CmdMessage: MessageByApplyGroup,
		ReceiveUserIds: masterGroup,
		SendUserID:     userId,
		SendUser:       userData,
		Content: map[string]interface{}{
			MessageContentByContent:content,
		},
	}
	_ = pushMessage.Push()


	return nil
}

// ChatByApplyGroupReverse 邀请进入群组
func ChatByApplyGroupReverse(userId int64,ByUserId int64,groupId int64, content string)error{
	t := time.Now().Format(time.RFC3339)
	//查询对应群组成员
	groupFriendSql,args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?",groupId).WhereIn("identity_id",model.ChatGroupFriendByIdentityIdManager,model.ChatGroupFriendByIdentityIdAdministrator).ToSql()
	groupFriendSqlData,err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql,args...))

	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	groupFriendToKeyUserIdData := util.ArrayColumnByInt64(&groupFriendSqlData,"user_id")
	//检测是否有权限操作
	if groupFriendToKeyUserIdData[userId]["identity_id"].(int64) == model.ChatGroupFriendByIdentityIdOrdinary {
		return errors.New("您没有权限操作")
	}
	//检测用户是否已经在群组中
	if groupFriendToKeyUserIdData[ByUserId] != nil {
		return errors.New("当前用户是群成员")
	}
	//检测是否已经发送
	groupApplySql,args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("by_user_id = ?",userId).Where("group_id = ?",groupId).Where("status = ?",model.ChatApplyFriendGroupByStatusWaiting).ToSql()
	groupApplyData,err := sql_aid.DataToMap(model.PgSql.Query(groupApplySql,args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroupReverse", "查询是群组sql失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupApplyData) != 0 {
		return errors.New("请勿重复邀请该用户")
	}
	groupFriendToUserId := util.ArrayField(&groupFriendSqlData,"user_id")
	groupFriendToUserId = append(groupFriendToUserId,ByUserId)
	//发送邀请
	insertData := make(map[string]interface{})
	insertData["user_id"] = userId
	insertData["type_id"] = model.ChatApplyFriendGroupByTypeIdGroupReverse
	insertData["by_user_id"] = ByUserId
	insertData["group_id"] = groupId
	insertData["content"] = content
	insertData["status"] = model.ChatApplyFriendGroupByStatusWaiting
	insertData["refused_message"] = ""
	insertData["time_c"] = t
	insertData["time_u"] = t
	insertData["merge_user_ids"] = model.ChatApplyFriendGroupByMergeUserIdsToJson(groupFriendToUserId...)
	insertSql,args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).InsertByMap(insertData)
	_,err = model.PgSql.Exec(insertSql,args...)
	if err != nil {
		gogo_log.Error("server_ChatByApplyGroup", "申请消息失败", err.Error())
		return errors.New("操作失败")
	}
	//发送通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	pushMessage := MessageByStructMain{
		CmdMessage: MessageByApplyGroupReverse,
		ReceiveUserIds: groupFriendToUserId,
		SendUserID:     userId,
		SendUser:       userData,
		Content: map[string]interface{}{
			MessageContentByContent:content,
			MessageContentByGroupId:groupId,

		},
	}
	_ = pushMessage.Push()


	return nil
}

// ChatByApplyList 申请列表
func ChatByApplyList(userId int64, page string, limit string) []map[string]interface{} {
	applySql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("merge_user_ids @> ?",fmt.Sprintf("[{\"user_id\":%v}]",userId) ).OrderBy("id desc").PageSize(page, limit).ToSql()
	applyData, err := sql_aid.DataToMap(model.PgSql.Query(applySql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyList", "查询数据失败", err.Error())
		return []map[string]interface{}{}
	}
	//获取申请人的信息
	byUserIds := util.ArrayField(&applyData, "by_user_id")
	userIds := util.ArrayField(&applyData, "user_id")
	userdataByKeyUserId := model.UserByIdsToData(&byUserIds,&userIds)
	//获取组信息
	groupIds := util.ArrayField(&applyData, "group_id")
	ChatGroupByKeyGroupId := model.ChatGroupToData(groupIds...)

	for _, datum := range applyData {
		if userdataByKeyUserId[datum["by_user_id"].(int64)] != nil {
			datum["by_user"] = userdataByKeyUserId[datum["by_user_id"].(int64)]
		}
		if userdataByKeyUserId[datum["user_id"].(int64)] != nil {
			datum["user"] = userdataByKeyUserId[datum["user_id"].(int64)]
		}
		if ChatGroupByKeyGroupId[datum["group_id"].(int64)] != nil {
			datum["group"] = userdataByKeyUserId[datum["group_id"].(int64)]
		}


	}
	return applyData
}

// ChatByApplyCheck 审核申请的消息
func ChatByApplyCheck(userId int64, applyId int64, status int64, content string) error {
	applySql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?", applyId).ToSql()
	applyData, err := sql_aid.DataToMap(model.PgSql.Query(applySql, args...))
	if err != nil {
		gogo_log.Error("server_ChatByApplyCheck", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if len(applyData) == 0 {
		return errors.New("数据不存在")
	}
	if applyData[0]["status"].(int64) != model.ChatApplyFriendGroupByStatusWaiting {
		return errors.New("当前审核已经处理")
	}
	switch applyData[0]["type_id"].(int64) {
	case model.ChatApplyFriendGroupByTypeIdFriend: //加好友
		err = chatByApplyCheckFriend(userId,applyData[0], status, content)
		break
	case model.ChatApplyFriendGroupByTypeIdGroup: //申请加入群
		err = chatByApplyCheckGroup(userId,applyData[0], status, content)
		break
	case model.ChatApplyFriendGroupByTypeIdGroupReverse: //群邀请用户
		err = chatByApplyCheckGroupReverse(userId,applyData[0], status, content)
		break
	default:
		return errors.New("当前数据类型无法处理")
	}
	if err != nil {
		return err
	}
	return nil
}

//审核申请的消息-》申请好友审核
func chatByApplyCheckFriend(userId int64,applyData map[string]interface{}, status int64, content string) error {
	if applyData["by_user_id"].(int64) != userId {
		return errors.New("您无权操作申请")
	}

	t := time.Now().Format(time.RFC3339)
	tx, err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByApplyCheck", "事务开启失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	//审核表更改状态
	applyUpdate := make(map[string]interface{})
	applyUpdate["status"] = status
	applyUpdate["time_u"] = t
	applyUpdate["refused_message"] = content
	applyUpdateSql, args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?", applyData["id"]).UpdateByMap(applyUpdate)
	_, err = tx.Exec(applyUpdateSql, args...)
	if err != nil {
		gogo_log.Error("server_ChatByApplyCheck", "申请表更改状态失败", err.Error())
		return errors.New("内部错误")
	}
	if status == model.ChatApplyFriendGroupByStatusAgree { //同意进行在数据库中添加
		friendInserts := make([]map[string]interface{}, 0)
		friendInsert := make(map[string]interface{})
		friendInsert["user_id"] = applyData["user_id"]
		friendInsert["friend_id"] = applyData["by_user_id"]
		friendInsert["time_c"] = t
		friendInserts = append(friendInserts, friendInsert)
		friendInsert = make(map[string]interface{})
		friendInsert["user_id"] = applyData["by_user_id"]
		friendInsert["friend_id"] = applyData["user_id"]
		friendInsert["time_c"] = t
		friendInserts = append(friendInserts, friendInsert)
		friendInsertsSql, args := sql_aid.PgTable(model.TableByChatFriend).InsertAllByMap(&friendInserts)
		_, err = tx.Exec(friendInsertsSql, args...)
		if err != nil {
			gogo_log.Error("server_ChatByApplyCheck", "好友表增加失败", err.Error())
			return errors.New("内部错误")
		}
		userMessageInserts := make([]map[string]interface{}, 0)
		userMessageInsert := make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["user_id"]
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["is_type"] = model.UserMessageByTypeIdFriend
		userMessageInsert["received_id"] = applyData["by_user_id"]
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = t
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInserts = append(userMessageInserts, userMessageInsert)
		userMessageInsert = make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["by_user_id"]
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["is_type"] = model.UserMessageByTypeIdFriend
		userMessageInsert["received_id"] = applyData["user_id"]
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = t
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInserts = append(userMessageInserts, userMessageInsert)
		userMessageInsertsSql, args := sql_aid.PgTable(model.TableByUserMessage).InsertAllByMap(&userMessageInserts)
		_, err = tx.Exec(userMessageInsertsSql, args...)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "用户消息表增加失败", err.Error())
			return errors.New("内部错误")
		}
		//消息推送
		userData, err := model.UserByInfo(applyData["by_user_id"].(int64))
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage: MessageByApplyFriendCheckAgree,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     applyData["by_user_id"].(int64),
			SendUser:       userData,
			Content: map[string]interface{}{
				MessageContentByContent:content,
			},
		}
		_ = pushMessage.Push()
	} else {
		//发送拒绝消息
		userData, err := model.UserByInfo(applyData["by_user_id"].(int64))
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage: MessageByApplyFriendCheckRefused,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     applyData["by_user_id"].(int64),
			SendUser:       userData,
			Content: map[string]interface{}{
				MessageContentByContent:content,
			},
		}
		_ = pushMessage.Push()
	}
	tx.Commit()
	return nil

}

//审核申请的消息-》申请进群审核
func chatByApplyCheckGroup(userId int64,applyData map[string]interface{}, status int64, content string) error{
	//不允许自己审核自己的信息
	if applyData["user_id"].(int64) == userId{
		return errors.New("您无法审核自己提交的信息")
	}
	//检测是否有权限操作
	ok := model.ChatApplyFriendGroupByIsMergeUserIds(applyData["merge_user_ids"].(string),userId)
	if ok == false {
		return errors.New("您无权操作申请")
	}
	//群组是否超出最大人员数量
	chatGroupSql ,args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?",applyData["group_id"].(int64)).ToSql()
	chatGroupData,err := sql_aid.DataToMap(model.PgSql.Query(chatGroupSql ,args...))
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询群信息错误", err.Error())
		return errors.New("内部错误")
	}
	if len(chatGroupData) == 0 {
		return errors.New("群组不存在")
	}
	if chatGroupData[0]["people_number"].(int64) >=1000{
		return errors.New("群组超出最大人数")
	}
	//给用户加入群组
	tx,err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now().Format(time.RFC3339)
	//申请操作
	applyUpdate := make(map[string]interface{})
	applyUpdate["status"] =status
	applyUpdate["by_user_id"] =userId
	applyUpdate["time_u"] = t
	applyUpdate["refused_message"] = content
	applyUpdateSql,args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?",applyData["id"]).UpdateByMap(applyUpdate)
	_,err = tx.Exec(applyUpdateSql,args...)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if status == model.ChatApplyFriendGroupByStatusAgree { //同意进行在数据库中添加
		//用户进群
		groupInsert := make(map[string]interface{})
		groupInsert["user_id"] = applyData["user_id"].(int64)
		groupInsert["group_id"] = applyData["group_id"].(int64)
		groupInsert["group_note"] = chatGroupData[0]["name"].(string)
		groupInsert["time_c"] = t
		groupInsert["identity_id"] = model.ChatGroupFriendByIdentityIdOrdinary
		var groupId int64
		groupInsertSql ,args := sql_aid.PgTable(model.TableByChatGroupFriend).InsertByMap(groupInsert)
		err = tx.QueryRow(groupInsertSql+" RETURNING id", args...).Scan(&groupId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群成员表添加错误", err.Error())
			return errors.New("内部错误")
		}
		//群组人员数量+1
		groupSql ,args := sql_aid.PgTable(model.TableByChatGroup).Inc("people_number",1).UpdateByMap(make(map[string]interface{}))
		_,err = tx.Exec(groupSql ,args...)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群表人员+1错误", err.Error())
			return errors.New("内部错误")
		}
		//增加用户对应得群消息
		userMessageInsert := make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["user_id"].(int64)
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["type_id"] = model.UserMessageByTypeIdGroup
		userMessageInsert["received_id"] = applyData["group_id"].(int64)
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = t
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInsert["new_content"] = ""
		userMessageInsertSql,args := sql_aid.PgTable(model.TableByUserMessage).InsertByMap(userMessageInsert)
		_,err = tx.Exec(userMessageInsertSql ,args...)
		//消息推送
		//向群内所有人进行推送
		groupsql,args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?",applyData["group_id"].(int64)).ToSql()
		groupData ,_ := sql_aid.DataToMap(tx.Query(groupsql,args...))
		groupUserIds := util.ArrayField(&groupData,"user_id")
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage: MessageByApplyGroupCheckAgree,
			ReceiveUserIds: groupUserIds,
			SendUserID:    userId,
			SendUser:       userData,
			Content: map[string]interface{}{
				MessageContentByContent:content,
			},
		}
		_ = pushMessage.Push()

	}else{
		//消息推送
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		fmt.Println(applyData["user_id"])
		pushMessage := MessageByStructMain{
			CmdMessage: MessageByApplyGroupCheckRefused,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     userId,
			SendUser:       userData,
			Content: map[string]interface{}{
				MessageContentByContent:content,
			},
		}
		_ = pushMessage.Push()
	}
	tx.Commit()
	return nil
}

//审核申请的消息-》邀请进群审核
func chatByApplyCheckGroupReverse(userId int64,applyData map[string]interface{}, status int64, content string)error{
	if applyData["by_user_id"].(int64) != userId{
		return errors.New("您无权操作申请")
	}
	chatGroupSql ,args := sql_aid.PgTable(model.TableByChatGroup).Where("id = ?",applyData["group_id"].(int64)).ToSql()
	chatGroupData,err := sql_aid.DataToMap(model.PgSql.Query(chatGroupSql ,args...))
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询群信息错误", err.Error())
		return errors.New("内部错误")
	}
	if len(chatGroupData) == 0 {
		return errors.New("群组不存在")
	}
	if chatGroupData[0]["people_number"].(int64) >=1000{
		return errors.New("群组超出最大人数")
	}
	//给用户加入群组
	tx,err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	t := time.Now().Format(time.RFC3339)
	//申请操作
	applyUpdate := make(map[string]interface{})
	applyUpdate["status"] =status
	applyUpdate["time_u"] = t
	applyUpdate["refused_message"] = content
	applyUpdateSql,args := sql_aid.PgTable(model.TableByChatApplyFriendGroup).Where("id = ?",applyData["id"]).UpdateByMap(applyUpdate)
	_,err = tx.Exec(applyUpdateSql,args...)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckGroup", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if status == model.ChatApplyFriendGroupByStatusAgree { //同意进行在数据库中添加
		//用户进群
		groupInsert := make(map[string]interface{})
		groupInsert["user_id"] = applyData["by_user_id"].(int64)
		groupInsert["group_id"] = applyData["group_id"].(int64)
		groupInsert["group_note"] = chatGroupData[0]["name"].(string)
		groupInsert["time_c"] = t
		groupInsert["identity_id"] = model.ChatGroupFriendByIdentityIdOrdinary
		var groupId int64
		groupInsertSql ,args := sql_aid.PgTable(model.TableByChatGroupFriend).InsertByMap(groupInsert)
		err = tx.QueryRow(groupInsertSql+" RETURNING id", args...).Scan(&groupId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群成员表添加错误", err.Error())
			return errors.New("内部错误")
		}
		//群组人员数量+1
		groupSql ,args := sql_aid.PgTable(model.TableByChatGroup).Inc("people_number",1).UpdateByMap(make(map[string]interface{}))
		_,err = tx.Exec(groupSql ,args...)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckGroup", "群表人员+1错误", err.Error())
			return errors.New("内部错误")
		}
		//增加用户对应得群消息
		userMessageInsert := make(map[string]interface{})
		userMessageInsert["user_id"] = applyData["by_user_id"].(int64)
		userMessageInsert["is_top"] = model.UserMessageByIsTopNo
		userMessageInsert["type_id"] = model.UserMessageByTypeIdGroup
		userMessageInsert["received_id"] = applyData["group_id"].(int64)
		userMessageInsert["unread_number"] = 0
		userMessageInsert["time_u"] = t
		userMessageInsert["status"] = model.UserMessageByStatusShow
		userMessageInsert["new_content"] = ""
		userMessageInsertSql,args := sql_aid.PgTable(model.TableByUserMessage).InsertByMap(userMessageInsert)
		_,err = tx.Exec(userMessageInsertSql ,args...)
		//向群内所有人进行推送
		groupsql,args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("group_id = ?",applyData["group_id"].(int64)).ToSql()
		groupData ,_ := sql_aid.DataToMap(tx.Query(groupsql,args...))
		groupUserIds := util.ArrayField(&groupData,"user_id")
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		pushMessage := MessageByStructMain{
			CmdMessage: MessageByApplyGroupReverseCheckAgree,
			ReceiveUserIds: groupUserIds,
			SendUserID:    userId,
			SendUser:       userData,
			Content: map[string]interface{}{
				MessageContentByContent:content,
			},
		}
		_ = pushMessage.Push()
	}else{
		//审核人信息
		userData, err := model.UserByInfo(userId)
		if err != nil {
			gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
			return errors.New("用户不存在")
		}
		fmt.Println(applyData["user_id"])
		pushMessage := MessageByStructMain{
			CmdMessage: MessageByApplyGroupReverseCheckRefused,
			ReceiveUserIds: []interface{}{applyData["user_id"]},
			SendUserID:     userId,
			SendUser:       userData,
			Content: map[string]interface{}{
				MessageContentByContent:content,
			},
		}
		_ = pushMessage.Push()
	}
	tx.Commit()
	return nil
}

// ChatByFriendList 好友列表
func ChatByFriendList(userId int64,page string,limit string)[]map[string]interface{}{
	friendSql,args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?",userId).PageSize(page,limit).ToSql()
	friendData,err := sql_aid.DataToMap(model.PgSql.Query(friendSql,args...))
	if err != nil {
		gogo_log.Error("server_ChatByFriendList", "查询数据失败", err.Error())
		return nil
	}
	friendIds := util.ArrayField(&friendData,"friend_id")
	userIdData := model.UserByIdsToData(&friendIds)
	for _, datum := range friendData {
		if userIdData[datum["friend_id"].(int64)] != nil {
			datum["friend"] = userIdData[datum["friend_id"].(int64)]
		}
	}
	return friendData
}

// ChatBySendMessage 发送消息
func ChatBySendMessage(typeId int64,userId int64,receivedId int64,content string)error{
	var err error
	switch typeId {
	case model.ChatMessageLogByTypeIdFriend:
		err = chatBySendMessageFriend(userId,receivedId,content)
		break
	case model.ChatMessageLogByTypeIdGroup:
		err = chatBySendMessageGroup(userId,receivedId,content)
		break
	default:
		return errors.New("未找到对应功能")
	}
	if err != nil {
		return err
	}
	return nil
}

//发送消息->发送好友
func chatBySendMessageFriend(userId int64,receivedId int64,content string)error{
	t := time.Now().Format(time.RFC3339)
	friendSql,args := sql_aid.PgTable(model.TableByChatFriend).Where("user_id = ?",receivedId).Where("friend_id = ?",userId).ToSql()
	friendData,err := sql_aid.DataToMap(model.PgSql.Query(friendSql,args...))
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if len(friendData) == 0 {
		return errors.New("对方还不是您的好友")
	}
	tx,err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	insertMessage := make(map[string]interface{})
	insertMessage["send_user_id"] = userId
	insertMessage["type_id"] = model.ChatMessageLogByTypeIdFriend
	insertMessage["received_id"] = receivedId
	insertMessage["content"] = content
	insertMessage["fallback_user_id"] = 0
	insertMessage["time_c"] = t
	insertMessageSql,args := sql_aid.PgTable(model.TableByChatMessageLog).InsertByMap(insertMessage)
	_,err = tx.Exec(insertMessageSql,args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "消息添加错误", err.Error())
		return errors.New("内部错误")
	}
	//消息内容
	userMessageUpdate := make(map[string]interface{})
	userMessageUpdate["new_content"] = content
	userMessageUpdate["time_u"] = t
	userMessageUpdate["status"] = model.UserMessageByStatusShow
	//发给用户消息
	userMessageUpdateSql,args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?",model.UserMessageByTypeIdFriend).WhereIn("user_id",receivedId).WhereIn("received_id",userId,receivedId).Inc("unread_number",1).UpdateByMap(userMessageUpdate)
	_,err = tx.Exec(userMessageUpdateSql,args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "更改发送用户消息错误", err.Error())
		return errors.New("内部错误")
	}
	//发送消息通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	pushMessage := MessageByStructMain{
		CmdMessage: MessageByOnlyChat,
		ReceiveUserIds: []interface{}{userId,receivedId},
		SendUserID:     userId,
		SendUser:       userData,
		Content: map[string]interface{}{
			MessageContentByContent:content,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil

}

//发送消息->发送群
func chatBySendMessageGroup(userId int64,groupId int64,content string)error{
	t := time.Now().Format(time.RFC3339)
	//验证用户是否存在于群组
	groupFriendSql,args := sql_aid.PgTable(model.TableByChatGroupFriend).Where("user_id = ?",userId).Where("group_id = ?",groupId).ToSql()
	groupFriendData,err := sql_aid.DataToMap(model.PgSql.Query(groupFriendSql,args...))
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	if len(groupFriendData) == 0 {
		return errors.New("请线加入群组")
	}
	tx,err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	insertMessage := make(map[string]interface{})
	insertMessage["send_user_id"] = userId
	insertMessage["type_id"] = model.ChatMessageLogByTypeIdGroup
	insertMessage["received_id"] = groupId
	insertMessage["content"] = content
	insertMessage["fallback_user_id"] = 0
	insertMessage["time_c"] = t
	insertMessageSql,args := sql_aid.PgTable(model.TableByChatMessageLog).InsertByMap(insertMessage)
	_,err = tx.Exec(insertMessageSql,args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "消息添加错误", err.Error())
		return errors.New("内部错误")
	}
	//消息内容
	userMessageUpdate := make(map[string]interface{})
	userMessageUpdate["new_content"] = content
	userMessageUpdate["time_u"] = t
	userMessageUpdate["status"] = model.UserMessageByStatusShow
	//发给用户消息
	userMessageUpdateSql,args := sql_aid.PgTable(model.TableByUserMessage).Where("type_id = ?",model.UserMessageByTypeIdGroup).Where("received_id = ?",groupId).Inc("unread_number",1).UpdateByMap(userMessageUpdate)
	_,err = tx.Exec(userMessageUpdateSql,args...)
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "更改发送用户消息错误", err.Error())
		return errors.New("内部错误")
	}

	//发送消息通知
	userData, err := model.UserByInfo(userId)
	if err != nil {
		gogo_log.Error("server_chatByApplyCheckFriend", "查询消息失败", err.Error())
		return errors.New("用户不存在")
	}
	//群组所有成员
	groupFriendSql,args = sql_aid.PgTable(model.TableByChatGroupFriend).Field("user_id").Where("group_id = ?",groupId).ToSql()
	groupFriendData,err = sql_aid.DataToMap(model.PgSql.Query(groupFriendSql,args...))
	if err != nil {
		gogo_log.Error("server_chatBySendMessageFriend", "查询数据失败", err.Error())
		return errors.New("内部错误")
	}
	groupFriendDataToUserId := util.ArrayField(&groupFriendData,"user_id")
	pushMessage := MessageByStructMain{
		CmdMessage: MessageByGroupChat,
		ReceiveUserIds: groupFriendDataToUserId,
		SendUserID:     userId,
		SendUser:       userData,
		Content: map[string]interface{}{
			MessageContentByContent:content,
		},
	}
	_ = pushMessage.Push()
	tx.Commit()
	return nil
}

// ChatByCreateGroup 创建群
func ChatByCreateGroup(userId int64,name string,introduce string)(map[string]interface{},error){
	t := time.Now().Format(time.RFC3339)
	tx,err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "事务启动失败", err.Error())
		return nil, errors.New("内部错误")
	}
	defer tx.Rollback()
	insertGroup := make(map[string]interface{})
	insertGroup["master_id"] = userId
	insertGroup["name"] = name
	insertGroup["introduce"] = introduce
	insertGroup["people_number"] = 1
	insertGroup["time_c"] = t
	var groupId int64
	insertGroupSql,args := sql_aid.PgTable(model.TableByChatGroup).InsertByMap(insertGroup)
	err = tx.QueryRow(insertGroupSql+" RETURNING id", args...).Scan(&groupId)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "创建群失败", err.Error())
		return nil, errors.New("内部错误")
	}
	insertGroupFriend := make(map[string]interface{})
	insertGroupFriend["user_id"] = userId
	insertGroupFriend["group_id"] = groupId
	insertGroupFriend["group_note"] = name
	insertGroupFriend["time_c"] = t
	insertGroupFriend["identity_id"] = model.ChatGroupFriendByIdentityIdManager
	insertGroupFriendSql,args := sql_aid.PgTable(model.TableByChatGroupFriend).InsertByMap(insertGroupFriend)
	_,err = tx.Exec(insertGroupFriendSql,args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "添加组信息失败", err.Error())
		return nil, errors.New("内部错误")
	}
	insertUserMessage := make(map[string]interface{})
	insertUserMessage["user_id"] = userId
	insertUserMessage["is_top"] = model.UserMessageByIsTopNo
	insertUserMessage["type_id"] = model.UserMessageByTypeIdGroup
	insertUserMessage["received_id"] = groupId
	insertUserMessage["unread_number"] = 0
	insertUserMessage["time_u"] = t
	insertUserMessage["status"] = model.UserMessageByStatusShow
	insertUserMessage["new_content"] = ""
	insertUserMessageSql,args := sql_aid.PgTable(model.TableByUserMessage).InsertByMap(insertUserMessage)
	_,err = tx.Exec(insertUserMessageSql,args...)
	if err != nil {
		gogo_log.Error("server_ChatByCreateGroup", "添加用户消息错误", err.Error())
		return nil, errors.New("内部错误")
	}
	tx.Commit()
	insertGroup["id"] = groupId
	return insertGroup,nil
}

// ChatByCleanMessage 消除接收到得消息
func ChatByCleanMessage(userId int64, userMessageId int64)error{
	tx,err := model.PgSql.Begin()
	if err != nil {
		gogo_log.Error("server_ChatByCleanMessage", "事务启动失败", err.Error())
		return errors.New("内部错误")
	}
	defer tx.Rollback()
	dataUpdate := make(map[string]interface{})
	dataUpdate["unread_number"] = 0
	dataSql,args := sql_aid.PgTable(model.TableByUserMessage).Where("user_id = ?",userId).WhereRaw(func(query *sql_aid.PgQuery, i ...interface{}) {
		if i[0].(int64) != 0 {
			query.Where("id = ?",i[0])
		}
	},userMessageId).UpdateByMap(dataUpdate)
	_,err = tx.Exec(dataSql,args...)
	if err != nil {
		gogo_log.Error("server_ChatByCleanMessage", "清理消息条数失败", err.Error())
		return errors.New("操作失败")
	}
	//发送消息通知
	pushMessage := MessageByStructMain{
		CmdMessage: MessageByApplyUserMessageClean,
		ReceiveUserIds: []interface{}{userId},
		Content: map[string]interface{}{
			MessageContentByContent:userMessageId,
		},
	}
	_ = pushMessage.Push()

	tx.Commit()
	return nil
}
